#!/bin/bash
#
# Copyright 2015-2017 Adrian DC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# === Device Shortcuts ===
function cdd()
{
  # Usage: cdd <device_name> (Access device sources)

  # Variables
  local content;
  local path;

  # Shortcut
  content=${1};
  if [ -z "${content}" ]; then
    content=$(repogetdevice);
  fi;

  # Path generation
  path=$(pwd | sed "s/\(.*\)Android\([^/]*\/[^/]*\).*/\1Android\2\/device\/*\/*${content}*/g");
  for path_item in ${path}; do
    if [ -d "${path_item}" ] && [[ ! "${path_item}" == *'generic'* ]] && [[ ! "${path_item}" == *'/qcom/'* ]]; then
      path=${path_item};
      break;
    fi;
  done;

  # Check path
  if [ ! -d "${path}" ]; then
    path=$(find ./*"${1}"* -type d -depth 0 2> /dev/null | head -n 1);
    if [ -z "${path}" ]; then
      echo " cdd: '${1}' not found...";
      return;
    fi;
  fi;

  # Access path
  cd "${path}";
}

# === Project Access ===
function cdp()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: cdp [project_name] (Access repo project sources)';
    echo '';
    return;
  fi;

  # Variables
  local cnt=0;
  local key;
  local path;
  local list_paths=('');
  local top;

  # Acquire repo path
  top=$(gettop);

  # Parse projects list to find first match
  while IFS= read -r path; do
    path=${path%/};
    if [[ "${path##*/}" == *"${1}"* ]]; then
      cnt=$((cnt + 1));
      list_paths+=("${path}");
    fi;
  done < "${top}/.repo/project.list";

  # Single input available
  if [ "${cnt}" -eq 0 ]; then
    echo '';
    echo -e " \e[1;37m[ Android Development Shell Tools - No project found ]\e[0m";
    echo '';

  # Single input available
  elif [ "${cnt}" -eq 1 ]; then
    cd "${top}/${list_paths[1]}";

  # Multiple inputs available
  else
    echo '';
    echo -e " \e[1;37m[ Android Development Shell Tools - Available project paths ]\e[0m";
    echo '';

    # Display paths menu
    cnt=0;
    for path in "${list_paths[@]}"; do
      if [ -z "${path}" ]; then
        continue;
      fi;
      cnt=$((cnt + 1));
      echo -e "  \e[1;33m${cnt}: \e[1;37m${path}\e[0m";
    done;
    echo '';

    # Request user input
    echo -n " > Path to select [1-${cnt}] : ";
    read -r key;
    echo '';

    # Access requested path
    cd "${top}/${list_paths[${key}]}";
  fi;
}

# === Repo Manifests ===
function cdman()
{
  # Usage: cdman (Access manifests path)

  # Variables
  local path;

  # Access manifests path
  path=$(pwd \
       | sed "s/\(.*\)Android\([^/]*\/[^/]*\).*/\1Android\2\/.repo\/manifests/g");
  mkdir -p "${path}/";
  cd "${path}/";
}

# === Repo Local Manifests ===
function cdlocman()
{
  # Usage: cdlocman (Access local manifests path)

  # Variables
  local path;

  # Access local manifests path
  path=$(pwd \
       | sed "s/\(.*\)Android\([^/]*\/[^/]*\).*/\1Android\2\/.repo\/local_manifests/g");
  mkdir -p "${path}/";
  cd "${path}/";
}

# === Repo Out Getter ===
function toout()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: toout <device_name> (Get device build output path)';
    echo '';
    return;
  fi;

  # Variables
  local device=${1};
  local outtargetpath;
  local outtargetpaths;

  # Get out target path
  outtargetpath=$(pwd | sed "s/\(.*\)Android\([^/]*\/[^/]*\).*/\1Android\2\/out\/target\/product/g");

  # Path detection
  outtargetpaths=("${outtargetpath}/"*"${device}"*);
  if [ "${#outtargetpaths[@]}" -ne 1 ]; then
    outtargetpaths=("${outtargetpath}/"*);
  fi;

  # Return path result
  echo "${outtargetpaths[0]}";
}

# === Repo Out Access ===
function cdout()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: cdout [device_name] (Access device build output path)';
    echo '';
    return;
  fi;

  # Access out path
  cd "$(toout "${1}")";
}

# === Find Android Dev Drive ===
function getand()
{
  # Usage: getand (Get AndroidDev drive)

  # Variables
  local android_dev_dir=${PWD};

  # Parent navigation
  while [[ "${android_dev_dir}" != '/' && ! -d "${android_dev_dir}/Bash" ]]; do
    android_dev_dir=$(readlink -f "${android_dev_dir}/..");
  done;

  # Return Bash location
  if [ -d "${android_dev_dir}/Bash" ]; then
    echo "${android_dev_dir}";
  else
    echo "${ANDROID_DEV_DRIVE}";
  fi;
}

# === Repo ROM Shortcut ===
function torompaths()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: torompaths <rom_name> [device] (Get ROM device variant path)';
    echo '';
    return;
  fi;

  # Variables
  local android_dev_dir;
  local targets=();
  local target=;

  # AndroidDev access
  android_dev_dir=$(getand);

  # AndroidDev verification
  if [ -z "${android_dev_dir}" ]; then
    echo '';
    echo 'Android drive with "Bash" not found...';
    echo '';
    return;
  fi;

  # AndroidDev access
  if ! pwd | grep -q "${android_dev_dir}"; then
    cdand;
  fi;

  # AndroidDev escaping
  android_dev_dir=${android_dev_dir//\//\\\/};

  # ROM subpath
  if [ ! -z "${2}" ]; then
    for targets in $(pwd | sed "s/\(${android_dev_dir}\)\(\/[^/]*\(.*\)\|\)$/\1\/${1}-*${2}*\3/g"); do
      target=$(echo "${targets[*]}" | cut -f1 -d\ );
    done;
  fi;

  # ROM path
  if [ -z "${target}" ] || [ ! -d "${target}" ]; then
    target=$(pwd | sed "s/\(${android_dev_dir}\)\(\/[^/]*\(.*\)\|\)$/\1\/${1}\3/g");
    target=$(echo "${target}" | cut -f1 -d\ );
  fi;

  # Mismatching ROM path
  if [ -z "${target}" ] || [ ! -d "${target}" ]; then
    cdand;
    target=$(pwd | sed "s/\(${android_dev_dir}\)\(\/[^/]*\(.*\)\|\)$/\1\/${1}\3/g");
    target=$(echo "${target}" | cut -f1 -d\ );
  fi;

  # Return target
  readlink -f "${target}/";
}

# === Check Command for Path Changes ===
function pathchanged()
{
  # Usage: pathchanged <command> <parameters> (Run command and notify path changes)

  # Variables
  local path;

  # Save current path;
  path=$(pwd);

  # Run input command
  "${@}";

  # Notify path differences
  [ "${path}" = "$(pwd)" ];
}

# === ROMs Shortcuts ===
function toaosp()       { torompaths 'AOSP' "${1}"; }
function tolineage()    { torompaths 'LineageOS' "${1}"; }
function toaospcaf()    { toaosp 'AOSP' 'CAF'; }
function tomultirom()   { torompaths 'MultiROM'; }
function torr()         { torompaths 'ResurrectionRemix' "${1}"; }
function totwrp()       { torompaths 'TWRP'; }
function cdaosp()       { cd "$(toaosp "${1}")"; }
function cdl()          { cd "$(tolineage "${1}")"; }
function cdlineage()    { cd "$(tolineage "${1}")"; }
function cdaospcaf()    { cd "$(toaospcaf)"; }
function cdmultirom()   { cd "$(tomultirom)"; }
function cdrr()         { cd "$(torr "${1}")"; }
function cdtwrp()       { cd "$(totwrp)"; }

# === Private Shortcuts ===
function cdand()        { cd "$(getand)"; }
function cddesk()       { cd "$(desktoppath)"; }
function cddev()        { cd "$(getand)/Development/${1}" 2> /dev/null; }
function cddevaosp()    { cd "$(getand)/Development/aosp_"*"${1}" 2> /dev/null; }
function cddevlineage() { cd "$(getand)/Development/lineage_"*"${1}" 2> /dev/null; }
function cddevmrom()    { cd "$(getand)/Development/multirom_development_sony" 2> /dev/null; }
function cddevtwrp()    { cd "$(getand)/Development/twrp_development_sony" 2> /dev/null; }
function cdprojects()   { cd "$(getand)/Projects/${1}"; }
function cdref()        { cd "$(getand)/References/${1}"; }
function cdrefapk()     { cd "$(getand)/References/apk"; }
function cdrefdev()     { cd "$(getand)/References/Devices/"${1:+*${1}}; }
function cdserv()       { cd "$(getand)/Server"; }
function adbapks()      { cdrefapk; adbapkinstall; }
function cdandfiles()   { cd "${ANDROID_FILES_PATH}/"; }
function impaospcaf()   { rsync -arv --delete --delete-after "$(toaospcaf "${1}")" "./${1}"; }
function implineage()   { rsync -arv --delete --delete-after "$(tolineage "${1}")" "./${1}"; }
function cpaosp()       { cp -fv "./${1}" "$(toaosp "${2}")/${1}"; }
function cplineage()    { cp -fv "./${1}" "$(tolineage "${2}")/${1}"; }
function meldaosp()     { meld "./${1}" "$(toaosp "${2}")/${1}"; }
function meldaospsony() { meld "./${1}" "$(toaosp sony)/${1}"; }
function meldaospcaf()  { meld "./${1}" "$(toaospcaf)/${1}"; }
function meldlineage()  { meld "./${1}" "$(tolineage "${2}")/${1}"; }
function meldmrom()     { meld "./${1}" "$(tomultirom)/${1}"; }
function meldtwrp()     { meld "./${1}" "$(totwrp)/${1}"; }
function nout()         { diropen "$(toout "${1}")"; }

# === Syncer Shortcuts ===
function aospsyncall() { reporeferencedaosp "reposy"; }
function lineagesyncall() { reporeferencedlineage "reposy"; }

# === BringUp Shortcuts ===
function meldril()
{
  # Usage: meldril [bool_caf] (Compare device to hardware/{ril|ril-caf})

  # Compare device to hardware/ril or hardware/ril-caf with a parameter given
  if [ ! -z "${1}" ]; then
    meld include/telephony/ril.h ../../../hardware/ril-caf/include/telephony/ril.h &
    meld libril ../../../hardware/ril-caf/libril;
  else
    meld include/telephony/ril.h ../../../hardware/ril/include/telephony/ril.h &
    meld libril ../../../hardware/ril/libril;
  fi;
}

# === Repository Shortcuts ===
function cdmromboot()  { croot; cd ./system/extras/libbootimg/; }
function cdmromcore()  { croot; cd ./system/extras/multirom/; }
function cdlsdk()      { croot; cd ./lineage-sdk/; }
function cdrecovery()  { croot; cd ./bootable/recovery/; }
function cdsepolicy()  { croot; cd ./system/sepolicy/; }
